package system;

import gui.DrawingPanel;
import gui.MainPanel;
import gui.MaskGrid;
import gui.MaskPanel;

import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.Stack;

/**
 * @author Kevin Peters
 */
public class PanelFactory {

	private static Map<Integer, ImagePart> imagePartMap;
	
	private static Stack<DrawingOperation> undoList = new Stack<DrawingOperation>();
	private static Stack<DrawingOperation> redoList = new Stack<DrawingOperation>();

	/**
	 * Adds all panel filled with ImageParts to the given MaskGrid
	 * 
	 * @param maskGrid
	 * @return Panels added
	 */
	public static int addPanels(MainPanel mainPanel, MaskGrid maskGrid,BufferedImage entireImage) {

		int curId;
		int panelsToAdd = SystemProperties.CANVASROWS
				* SystemProperties.CANVASCOLS;
		
		imagePartMap = ImageFactory.splitImage(entireImage,
				SystemProperties.RESOURCECOLS, SystemProperties.RESOURCEROWS);
		for (curId = 0; curId < panelsToAdd; curId++) {

			if (SystemProperties.FILLEDEDITORPANELS.contains(curId)) {

				int correctImagePartId = SystemProperties.PANELMAPPING_EDITOR2SOURCE
						.get(curId);

				ImagePart correctImagePart = imagePartMap
						.get(correctImagePartId);

				DrawingPanel currentDrawingPanel = new DrawingPanel(mainPanel,
						correctImagePart,undoList);

				maskGrid.announceDrawingPanel(currentDrawingPanel);

				maskGrid.add(currentDrawingPanel);
			} else {
				maskGrid.add(new MaskPanel(curId,
						SystemProperties.GRIDPANELSIDELENGTH));
			}

		}

		maskGrid.mapDrawingPanels();
		return curId;
	}
	
	/**
	 * Reverts the last action
	 * @return Actions left to undo 
	 */
	public static int performUndo(){
		
		if (!undoList.empty()){
			DrawingOperation drawingOperation = undoList.pop();
			drawingOperation.undo();
			redoList.push(drawingOperation);
		}
		
		return undoList.size();
		
	}
	
	/**
	 * Repeats the last action
	 * @return Actions left to redo 
	 */
	public static int performRedo(){
		
		if (!redoList.empty()){
			DrawingOperation drawingOperation = redoList.pop();
			drawingOperation.redo();
			undoList.push(drawingOperation);
		}
		
		return redoList.size();
		
	}
}
